home *** CD-ROM | disk | FTP | other *** search
/ Aminet 1 (Walnut Creek) / Aminet - June 1993 [Walnut Creek].iso / aminet / gfx / conv / ilbm24.lha / ilbm / readsunras.c < prev    next >
C/C++ Source or Header  |  1993-02-12  |  7KB  |  294 lines

  1. /*
  2.  *
  3.  * This function almost taken wholesale from the xv2.21 distribution.
  4.  *
  5.  * Slight modifications by Brett Van Sprewenburg
  6.  *     For relevant information on the xv disturbtion, get the xv display kit.
  7.  *
  8.  * Altered some return codes to return < 0 on error.
  9.  *
  10.  * LoadSunRas(fname)  -  loads a Raster pic
  11.  *
  12.  */
  13.  
  14. #include <writeilbm.h>
  15.  
  16. static int  SunRasError();
  17. static void  SunRas1to8();
  18. static int  rle_read();
  19. static void flipl();
  20. static void fixBGR();
  21. byte *pic, r[256], g[256], b[256];
  22. int pHIGH,pWIDE;
  23.  
  24. int LoadSunRas(char *fname)
  25. {
  26.   FILE    *fp;
  27.   int     linesize,lsize,csize,isize,flipit,i,w,h,d,rv;
  28.   byte     *image, *line;
  29.  
  30.   rv = 0;
  31.  
  32.   /* read in the Sun Rasterfile picture */
  33.   fp=fopen(fname,"r");
  34.   if (!fp) return( SunRasError("unable to open file") );
  35.  
  36.   flipit = FALSE;
  37.   fread(&sunheader,sizeof(struct RasterHeader),1,fp);
  38.   if (sunheader.ras_magic != RAS_MAGIC)
  39.   {
  40.     flipl( (byte *) &sunheader.ras_magic);
  41.     if (sunheader.ras_magic == RAS_MAGIC) flipit = TRUE;
  42.     else flipl( (byte *) &sunheader.ras_magic);
  43.   }
  44.   if (sunheader.ras_magic != RAS_MAGIC)  {
  45.     fprintf(stderr,"'%s' is not a Sun Raster file. Exiting.\n",fname);
  46.     fclose(fp);
  47.     return -1;
  48.   }
  49.  
  50.   if (flipit) {
  51.     flipl((byte *) &sunheader.ras_width);
  52.     flipl((byte *) &sunheader.ras_height);
  53.     flipl((byte *) &sunheader.ras_depth);
  54.     flipl((byte *) &sunheader.ras_length);
  55.     flipl((byte *) &sunheader.ras_type);
  56.     flipl((byte *) &sunheader.ras_maptype);
  57.     flipl((byte *) &sunheader.ras_maplength);
  58.     }
  59.  
  60.   /* make sure that the input picture can be dealt with */
  61.   if ( sunheader.ras_depth != 1 &&
  62.       sunheader.ras_depth != 8 && 
  63.       sunheader.ras_depth != 24 && 
  64.       sunheader.ras_depth != 32) {
  65.     fprintf (stderr, "Sun rasterfile image has depth %d\n", 
  66.          sunheader.ras_depth);
  67.     fprintf (stderr, "Depths supported are 1, 8, 24, and 32\n");
  68.     return -1;
  69.   }
  70.  
  71.   if (sunheader.ras_type != RT_OLD &&
  72.       sunheader.ras_type != RT_STANDARD &&
  73.       sunheader.ras_type != RT_BYTE_ENCODED &&
  74.       sunheader.ras_type != RT_FORMAT_RGB) {
  75.     fprintf (stderr, "Sun rasterfile of unsupported type %d\n",
  76.          sunheader.ras_type);
  77.     return -1;
  78.   }
  79.  
  80.   if (sunheader.ras_maptype != RMT_RAW &&
  81.       sunheader.ras_maptype != RMT_NONE &&
  82.       sunheader.ras_maptype != RMT_EQUAL_RGB) {
  83.     fprintf (stderr, "Sun rasterfile colormap of unsupported type %d\n",
  84.          sunheader.ras_maptype);
  85.     return -1;
  86.   }
  87.  
  88.   w = sunheader.ras_width;
  89.   h = sunheader.ras_height;
  90.   d = sunheader.ras_depth;
  91.   isize = sunheader.ras_length ?
  92.       sunheader.ras_length :
  93.       (w * h * d) / 8;
  94.   csize = (sunheader.ras_maptype == RMT_NONE) ? 0 : sunheader.ras_maplength;
  95.  
  96.   lsize = w * h;     
  97.   if (d == 24 || d == 32) lsize = lsize * 3;
  98.  
  99.   linesize = w * d;
  100.   /* if ((linesize % 48) && d == 24) linesize += (48 - (linesize % 48)); */
  101.   if (linesize % 16) linesize += (16 - (linesize % 16));
  102.   linesize /= 8;
  103.  
  104.   if (DEBUG)
  105.   {
  106.     fprintf(stderr,"readsunras: LoadSunRas() - loading a %dx%d pic, %d planes\n",
  107.         w, h,
  108.         d);
  109.     fprintf (stderr, 
  110.        "type %d, maptype %d, isize %d, csize %d, lsize %d, linesize %d\n",
  111.          sunheader.ras_type, sunheader.ras_maptype,
  112.          isize, csize, lsize, linesize);
  113.   }
  114.  
  115.  
  116.   fprintf(stderr,"%dx%d Sun %s rasterfile.  (%d plane%s)  (%d uncompressed bytes)\n",
  117.       sunheader.ras_width, sunheader.ras_height,
  118.       sunheader.ras_type == RT_BYTE_ENCODED ? "rle" : "standard",
  119.       d,
  120.       d == 1 ? "" : "s",
  121.       sizeof (struct RasterHeader) + csize + isize);
  122.  
  123.   /* read in the colormap, if any */
  124.   if (sunheader.ras_maptype == RMT_EQUAL_RGB && csize)
  125.   {
  126.     fread (r, sizeof (byte), sunheader.ras_maplength/3, fp);
  127.     fread (g, sizeof (byte), sunheader.ras_maplength/3, fp);
  128.     fread (b, sizeof (byte), sunheader.ras_maplength/3, fp);
  129.  
  130.   }
  131.   else if (sunheader.ras_maptype == RMT_RAW && csize)
  132.   {
  133.     /* we don't know how to handle raw colormap, ignore */
  134.     fseek (fp, (long) csize, 1);
  135.   }
  136.  
  137.   else {  /* no colormap, make one up */
  138.     if (sunheader.ras_depth == 1) {
  139.       r[0] = g[0] = b[0] = 0;
  140.       r[1] = g[1] = b[1] = 255;
  141.     }
  142.  
  143.     else if (sunheader.ras_depth == 8) {
  144.       for (i = 0; i < 256; i++)
  145.     r[i] = g[i]  = b[i] = i;
  146.     }
  147.   }
  148.  
  149.  
  150.   /* allocate memory for picture and read it in */
  151.   /* note we may slightly overallocate here (if image is padded) */
  152.   image = (byte *) malloc (lsize);
  153.   line = (byte *) malloc (linesize);
  154.   if (image == NULL || line == NULL)
  155.     fprintf(stderr,"Can't allocate memory for image\n");
  156.  
  157.   for (i = 0; i < h; i++) {
  158.     if (sunheader.ras_type == RT_BYTE_ENCODED) {
  159.       if (rle_read (line, 1, linesize, fp, (i==0)) != linesize) break;
  160.      return (SunRasError ("rle file read error")); 
  161.     }
  162.  
  163.     else {
  164.       if (fread (line, 1, linesize, fp) != linesize)
  165.     return (SunRasError ("file read error"));
  166.     }
  167.  
  168.     switch (d) {
  169.     case 1:  SunRas1to8 (image + w * i, line, w);    break;
  170.     case 8:  memcpy (image + w * i, line, w);        break; 
  171.     case 24: memcpy (image + w * i * 3, line, w * 3); break;
  172.     case 32: {
  173.                int k;
  174.                byte *ip, *op;
  175.            ip = line;
  176.            op = (byte *) (image + w * i * 3);
  177.            for (k = 0; k<w; k++) {
  178.          *ip++;           /* skip 'alpha' */
  179.          *op++ = *ip++;   /* red   */
  180.          *op++ = *ip++;   /* green */
  181.          *op++ = *ip++;   /* blue  */
  182.            }
  183.          }
  184.     }
  185.   }
  186.  
  187.   if (fp != stdin) fclose (fp);
  188.   if (DEBUG) fprintf(stderr,"Sun ras: image loaded!\n");
  189.  
  190.   if (d == 24 || d == 32)
  191.     if (sunheader.ras_type != RT_FORMAT_RGB) fixBGR(image,w,h);
  192.  
  193.   pic = image;
  194.   pWIDE = w;
  195.   pHIGH = h;
  196.   return 0;
  197. }
  198.  
  199.  
  200. /*****************************/
  201. static int rle_read (ptr, size, nitems, fp, init)
  202. byte *ptr;
  203. int size, nitems,init;
  204. FILE *fp;
  205. {
  206.   static int count, ch;
  207.   int readbytes, c, read;
  208.  
  209.   if (init) { count = ch = 0; }
  210.  
  211.   readbytes = size * nitems;
  212.   for (read = 0; read < readbytes; read++) {
  213.     if (count) {
  214.       *ptr++ = (byte) ch;
  215.       count--;
  216.     }
  217.  
  218.     else {
  219.       c = getc(fp);
  220.       if (c == EOF) break;
  221.  
  222.       if (c == RAS_RLE) {   /* 0x80 */
  223.     count = getc(fp);
  224.     if (count == EOF) break;
  225.  
  226.     if (count < 0) count &= 0xff;
  227.     if (count == 0) *ptr++ = c;
  228.         else {
  229.           if ((ch = getc(fp)) == EOF) break;
  230.           *ptr++ = ch;
  231.         }
  232.       }
  233.       else *ptr++ = c;
  234.     }
  235.   }
  236.  
  237.   return (read/size);
  238. }
  239.  
  240.  
  241. /*****************************/
  242. static int SunRasError(st)
  243. char *st;
  244. {
  245.   fprintf(stderr,"LoadSunRas() - %s",st);
  246.   return -1;
  247. }
  248.  
  249.  
  250. /*****************************/
  251. static void SunRas1to8 (dest, src, len)
  252. byte *dest, *src;
  253. int len;
  254. {
  255.   int i, b;
  256.   int c;
  257.  
  258.   for (i = 0, b = -1; i < len; i++) {
  259.     if (b < 0) {
  260.       b = 7;
  261.       c = ~*src++;
  262.     }
  263.     *dest++ = ((c >> (b--)) & 1);
  264.   }
  265. }
  266.  
  267.  
  268. /*****************************/
  269. static void flipl(p)
  270.      byte *p;
  271. {
  272.   byte t;
  273.   t = p[0];  p[0]=p[3];  p[3] = t;
  274.   t = p[1];  p[1]=p[2];  p[2] = t;
  275. }
  276.  
  277. /* kr3 - fix up BGR order SUN 24-bit rasters to be RGB order */
  278. static void fixBGR(img,w,h)
  279. unsigned char *img;
  280. int w,h;
  281. {
  282.   int i,npixels;
  283.   unsigned char tmp;
  284.  
  285.   npixels = w*h;
  286.   for (i=0; i<npixels; i++) {
  287.     tmp = img[0];                   /* swap red and blue channels */
  288.     img[0] = img[2];
  289.     img[2] = tmp;
  290.     img += 3;                       /* bump to next pixel */
  291.   }
  292. }
  293.  
  294.